<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title>Open Street Map</title>
		<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
		<style type="text/css" media="all">
			html, body, #map {
				width: 100%;
				height: 100%;
				margin: 0;
				position: relative;
				z-index: 0;
				font-family: sans-serif;
			}
			#search_form {
				position: absolute;
				z-index: 1;
				bottom: 2.5em;
				right: 0.5em;
			}
			#layout_switch {
				position: absolute;
				bottom: 15px;
				left: 140px;
				z-index: 1;
			}
			#layout_switch a {
				color: black;
			}
			#layout_switch a:visited {
				color: black;				
			}
			#layout_switch a:hover {
				color: white;
				background-color: black;
				opacity: 0.5;				
			}			
			.olControlPanZoom {
				top: auto !important;
				bottom: 173px; /* .olControlScaleLine.bottom = 15 + .olControlScaleLine.bottom = 26 + margin = 15px + #OpenLayers.Control.PanZoom_5_zoomout = 99 + #OpenLayers.Control.PanZoom_5_zoomout = 18 */
			}
			.olControlAttribution {
			    right: 0.5em !important;
			    bottom: 15px !important; 
			}
		</style>
		<script src="api/OpenLayers.js" type="text/javascript"></script>
		<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
		<script type="text/javascript">
			<!--
			
			/*
			 * OpenStreetMap Widget
			 * ==========================================================
			 * Copyright (C) Université Claude Bernard Lyon 1 (ICAP), Délégation Interministérielle à  l'Éducation Numérique en Afrique, Guillaume Burel, 2012
			 *
			 * This program is free software: you can redistribute it and/or modify
			 * it under the terms of the GNU General Public License as published by
			 * the Free Software Foundation, either version 3 of the License, or
			 * (at your option) any later version.
			 *
			 * This program is distributed in the hope that it will be useful,
			 * but WITHOUT ANY WARRANTY; without even the implied warranty of
			 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
			 * GNU General Public License for more details.
			 *
			 * You should have received a copy of the GNU General Public License
			 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
			 */
			 
			/* Geonames API identifier */
			var geonamesUser = "yimgo";

			/* map variable will be used to manipulate the map. This will be initialized like an OpenLayers.Map object. */
			var map;

			/* updateMap() allow user to modify the considered zone, in case a change has been requested (e.g. user request) */	
			function updateMap(coordinates) {
				/* transforming given coordinates, which have to be expressed in WGS-1984 projection, to map's projection */
				var position = new OpenLayers.LonLat(coordinates["lng"], coordinates["lat"]).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
				/* centering in position with given zoom */
				map.setCenter(position, coordinates["zoom"]);
			}				

			/* doSearch() performs the request to geonames server with the given query, and updates the map in case of success. */
			function doSearch(query) {
				/* performing request with JSON API from geonames and global username (identifying request's author). Asking for only one result, to save resources and to allow the user to avoid a choice when doing the research. */
				$.ajax({
					url: "http://api.geonames.org/searchJSON",
					dataType: 'json',
					data: { 
						q: encodeURIComponent(query),
						maxRows: "1",
						username: geonamesUser
					},
					success: function(data) {	
						/* updating the map if response is ok */
						if (typeof data["geonames"][0]!= 'undefined') {
							var coordinates = new Array();
							coordinates["lng"] = data["geonames"][0].lng;
							coordinates["lat"] = data["geonames"][0].lat;
							
							/* if position represents a country, setting the zoom to 6 */
							if (data["geonames"][0].fcl == "A")
								coordinates["zoom"] = 6;
							else
								coordinates["zoom"] = 12;
							
							updateMap(coordinates);
						}
					}
					
	  	  		});
			}

			/* 
			 * doNominatim() could use Nominatim API (http://wiki.openstreetmap.org/wiki/Nominatim).
			 * It is not used because first result is not always pertinent and we want to avoid user to make a choice after his request.
			 * Bounding box info provided by Nominatim could be a good way to set the right zoom for request (instead of having a determined zoom for countries and cities). 
			 * Nominatim allows user (the developer in this case) to set the language to display informations provided in sankoré user native language.
			 */
			function doNominatim(query) {
				$.ajax({
					url: "http://nominatim.openstreetmap.org/search",
					dataType: "json",
					data: { 
						q: query,
						format: "json",
						limit: "10",
						addressdetails: "1"
					},
					success: function(data) {	
						/* updating the map if response is ok */
						if (typeof data[0]!= 'undefined') {
							var coordinates = new Array();
							coordinates["lng"] = data[0].lon;
							coordinates["lat"] = data[0].lat;
							
							/* if position represents a city, setting the zoom to 12 */
							if (data[0].address.state)
								coordinates["zoom"] = 12;
							else
								coordinates["zoom"] = 6;
							
							updateMap(coordinates);
						}
					}
					
	  	  		});
			}

			function importData(data)
			{
				map.setCenter(new OpenLayers.LonLat(data["center"]["lon"], data["center"]["lat"]), data["zoom"]);
			}

			function exportData()
			{
				if (window.sankore)
        			sankore.setPreference("osm", JSON.stringify({center: map.getCenter(), zoom: map.getZoom()})); 
			}

			window.onload = function() {
				map = new OpenLayers.Map({
					div: "map"
				});

				/* limiting max zoom, by overriding OpenLayers.Map::moveTo function */
				map.newMoveTo = map.moveTo;
				map.moveTo = function(lonlat, zoom, options) {
    				return(zoom >= 0 && zoom <= 17) ? map.newMoveTo(lonlat,zoom,options) : false;
				};

				/* Standard layer */
				classic = new OpenLayers.Layer.OSM("Classic");

				/* avoiding out of bounds requests */
				classic.displayOutsideMaxExtent = false;

		    	/* Landscape layer */
		    	relief = new OpenLayers.Layer.OSM("Relief", [
		    		'http://a.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png',
                    'http://b.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png',
                    'http://c.tile3.opencyclemap.org/landscape/${z}/${x}/${y}.png'
            	]);
            	relief.displayOutsideMaxExtent = false;

				/* then adding layers to the map */
		    	map.addLayers([classic, relief]);

		    	/* displaying scale line, allowing user to represent distances */
				map.addControl(new OpenLayers.Control.ScaleLine());

	    		/* then zomming to get a better overview of the worldmap */
        		map.zoomTo(2);

				/* doSearch is called when form is submitted */
				$("#search_form").submit(function (event) {
					doSearch($("#query").val());
					return false;
				});

				/* allowing user to simply switch between classic and relief layers */
				$("#layout_switch > a").click(function (event) {
					newLayer = $(this).text() == "Relief" ? relief : classic;
					newText = $(this).text() == "Relief" ? "Classic" : "Relief";

					$(this).text(newText);
					map.setBaseLayer(newLayer);

					return false;
				});

				/* importing state from Sankoré preferences */
				if (window.sankore) {
			        if (sankore.preference("osm","")) {
			            importData(JSON.parse(sankore.preference("osm","")));
			        }
   				}

   				/* exporting state when receiving a leave event */
   				if (window.widget) {
			        window.widget.onleave = function() {
			            exportData();
			        }
			    }
			};
			-->
		</script>
	</head>
	<body>
		<div id="map">	  
		</div>

		<div id="layout_switch">
			<a href="#">Relief</a>
		</div>

		<form method="post" id="search_form" action="#" accept-charset="UTF-8">
			<p>
				<input type="text" value="" tabindex="1" id="query" />
				<input type="submit" value="Go" />
			</p>
		</form>
	</body>
</html>
